home *** CD-ROM | disk | FTP | other *** search
/ Belgian Amiga Club - ADF Collection / BS1 part 05.zip / BS1 part 5 / SASC_6.0_Disk_7.adf / Source_And_Examples / examples / avg / avg2.a < prev    next >
Encoding:
Text File  |  1992-07-30  |  5.3 KB  |  175 lines

  1. ;-------------------------------------------------------------------------- 
  2. ; Copyright (c) 1989,1990,1991,1992 by SAS Institute Inc., Cary NC
  3. ;
  4. ; Name       : avg2.a
  5. ; Author     : Michael S. Whitcher
  6. ; Date       : 02June92
  7. ; Description:
  8. ; Buildline  : asm avg2.a
  9. ;
  10. ;  Example assembler routine to demonstrate how 
  11. ;
  12. ;  -- to set up parameters being called from a 
  13. ;     C routine using stack and register passing conventions
  14. ;  -- to call a link library function using registerized parameters
  15. ;                     
  16. ;-------------------------------------------------------------------------- 
  17.  
  18.    INCLUDE "exec/macros.i"
  19.    INCLUDE "exec/libraries.i"
  20.    INCLUDE "dos/dos_lib.i"
  21.  
  22. ;-------------------------------------------------------------------------- 
  23. ;  These are the entrypoints defined in this module.
  24.    xdef _avg
  25.    xdef @avg
  26.    xdef _prnts
  27.  
  28. ;-------------------------------------------------------------------------- 
  29. ;  External routines
  30.    xref @__stcd_l
  31.   
  32. ;-------------------------------------------------------------------------- 
  33. ;  External data that I reference
  34. ;  This is actually defined in the startup code.
  35.    xref _DOSBase
  36.  
  37.  
  38.  
  39.    section text,code
  40.  
  41. ;-------------------------------------------------------------------------- 
  42. ; long avg(register __d0 int argc, register __a0 char **argv);
  43. ;      -- Computes the average of an array of numbers
  44. ;-------------------------------------------------------------------------- 
  45. ;  This is the stack based entry point into this function  
  46. ;  Move the parameters off the stack and back into register so that
  47. ;  we can drop through to the rest of the routine.
  48. _avg:
  49.    MOVE.L   4(SP),D0
  50.    MOVE.L   8(SP),A0
  51.  
  52. ;-------------------------------------------------------------------------- 
  53. ;  This is the registerized entry point into this function
  54. ;  Nothing extra to do in this case.
  55. @avg:   
  56.  
  57. ;  At function entry register D0 holds argc and A0 holds argv
  58.  
  59. ;  This is how to allocate storage for auto variables.
  60. ;  In this case, we need 4bytes to store the return value from a 
  61. ;  call to stcd_l() 
  62.    SUBQ.W      #4,SP
  63.    
  64. ;  Save the current value of these registers so that we can reuse them
  65. ;  below.  We will restore these registers at function exit.
  66.    MOVEM.L     D5-D7/A3,-(SP)
  67.  
  68. ;  Since argc and argv are both in scratch registers (registers that are 
  69. ;  not saved over function calls), move them to a location where they 
  70. ;  won't be destroyed.
  71.    MOVEA.L     A0,A3
  72.    MOVE.L      D0,D7
  73.    
  74. ;  Do some error checking to make sure argc looks reasonable.
  75.    TST.L       D7
  76.    BGT.B       sumval
  77.  
  78. ;  Error case (argc <= 0). Return an average of zero.
  79.    MOVEQ       #00,D0
  80.    BRA.B       avgret
  81.  
  82. sumval:
  83. ;  Convert the strings into numbers and sum them into register D6
  84. ;  If we get to here we are guaranteed to execute the loop at least once.
  85.    MOVEQ       #00,D6
  86.  
  87. ;  Use D5 as our loop counter
  88.    MOVEQ       #00,D5
  89.  
  90. avgloop:
  91. ;  Convert the number from string format into numeric form
  92. ;  Note:  The '@' on the JSR instruction means that this is the 
  93. ;  registerized parameter version.
  94.    MOVEA.L     (A3)+,A0
  95.    LEA         0010(SP),A1
  96.    JSR         @__stcd_l(PC)
  97.  
  98. ;  Accumulate our total
  99.    ADD.L       0010(SP),D6
  100.  
  101. ;  See if there is more to do
  102. ;  Increment our loop counter and compare against our termination value
  103.    ADDQ.L      #1,D5
  104.    CMP.L       D7,D5
  105.    BLT.B       avgloop
  106.    
  107. ;  Now that we have the sum, compute the average as (total/argc).
  108.    DIVS.W      D7,D6
  109.    EXT.L       D6
  110.    MOVE.L      D6,D0      
  111.  
  112. ;  Done; cleanup and return
  113. avgret:
  114.  
  115. ;  Restore saved registers
  116.    MOVEM.L     (SP)+,D5-D7/A3
  117.  
  118. ;  Release our automatic storage
  119.    ADDQ.W      #4,SP
  120.  
  121. ;  Away we go   
  122.    RTS
  123.  
  124. ;-----------------------------------------------------------------
  125. ; int __asm prnts(register __d0 BPTR fh,  register __a0 char *str);
  126. ;      -- write a string out to the given AmigaDos file handle
  127. ;      -- no error checking is done on the input file handle
  128. ;-----------------------------------------------------------------
  129. ; Setup a single entrypoint for this routine.   Parameters will 
  130. ; always be passed in register.  
  131. _prnts   
  132. ;  Here is our list of saved registers
  133.    MOVEM.L     D3/A3/A6,-(SP)
  134.  
  135. ;  Save the start of the string, because we will need it later
  136.    MOVEA.L     A0,A3
  137.  
  138. ;  We need to find the length of the string
  139. ;  Loop to count the number of characters until we find a NULL byte.
  140. ;  Note:  I use D3 here to hold the length of the string so that I
  141. ;  don't have to do a move when I go to do the write.
  142.  
  143.    MOVEQ       #00,D3
  144. prntloop:   
  145.    TST.B       (A0)+
  146.    BEQ.B       wrtstr
  147.    ADDQ.L      #1,D3
  148.    BRA.B       prntloop
  149.  
  150.  
  151. ;  Load up the needed registers to make the call to AmigaDos to write
  152. ;  out the string.  Note:  I don't have to worry about opening up dos.library
  153. ;  here because it is done for me in the startup code.     
  154. ;  By convention, calls into the AmigaDos libraries are done off of A6, and 
  155. ;  the macros in the header files reflect this.  If you were making several 
  156. ;  calls you would not have to reload this register before each call unless 
  157. ;  you had used it in the interum.
  158. wrtstr:
  159.    MOVE.L      D0,D1
  160.    MOVE.L      A3,D2
  161.    MOVEA.L     _DOSBase(A4),A6
  162.    JSR         _LVOWrite(A6)
  163.    
  164.  
  165. ;  The return value from Write() comes back in register D0 which is just where
  166. ;  we want it to return to our caller.
  167.  
  168.  
  169. ;  Restore saved registers
  170.    MOVEM.L     (SP)+,D3/A3/A6
  171.  
  172. ;  Away we go   
  173.    RTS
  174.    END
  175.